﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using System.Threading;
using System.Collections;
using System.Windows.Markup;
using System.Windows.Media;
using System.Net;
using System.Runtime.InteropServices;

namespace TestFireBroadcastingHostPhone.RelatedInstruments
{
    public class AN97002Todo
    {
        #region -- 相关数据定义
        /// <summary>
        /// ASCII码相关符号16进制转换
        /// </summary>
        public enum ASCII_ExchangeToHex : byte
        {
            /// <summary>
            /// ,逗号ASCII码转16进制
            /// </summary>
            Comma = 0x2C,
            /// <summary>
            /// ;分号ASCII码转16进制
            /// </summary>
            Semicolon = 0x3B,
            /// <summary>
            /// =等于号ASCII码转16进制
            /// </summary>
            Equal = 0x3D,
            /// <summary>
            /// *星号ASCII码转16进制
            /// </summary>
            Star = 0x2A
        }
        /// <summary>
        /// AN系列交流源通讯协议
        /// </summary>
        public enum An_CommunicationProtocol : byte
        {
            /// <summary>
            /// 帧头
            /// </summary>
            An_Header = 0x7B,
            /// <summary>
            /// 帧尾
            /// </summary>
            An_Frame = 0x7D,
        }
        /// <summary>
        /// AN97002程控交流源通讯波特率
        /// </summary>
        private const int AN97002_BaudRate = 9600;
        /// <summary>
        /// AN97002程控交流源通讯命令功能码
        /// </summary>
        public struct An_InstrumentSendCmd
        {
            /// <summary>
            /// 启动命令
            /// </summary>
            public enum An_InstrumentStrat : byte
            {
                One = 0x43,

                Two = 0x53,

                Three = 0x54,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 停止命令
            /// </summary>
            public enum An_InstrumentStop : byte
            {
                One = 0x43,

                Two = 0x53,

                Three = 0x50,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 设置参数命令
            /// </summary>
            public enum An_InstrumentSetData : byte
            {
                One = 0x53,

                Two = 0x4E,

                Three = 0x4F,

                Four = ASCII_ExchangeToHex.Equal,

                Five = ASCII_ExchangeToHex.Comma,

                Six = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 读取程控交流源型号命令
            /// </summary>
            public enum An_ReadInstrumentType : byte
            {
                One = 0x52,

                Two = 0x4D,

                Three = 0x4F,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 读取程控交流源版本命令
            /// </summary>
            public enum An_ReadInstrumentEdition : byte
            {
                One = 0x52,

                Two = 0x56,

                Three = 0x45,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 读取程控交流源状态命令
            /// </summary>
            public enum An_ReadInstrumentStatus : byte
            {
                One = 0x52,

                Two = 0x54,

                Three = 0x45,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 读取程控交流源数据结果命令
            /// </summary>
            public enum An_ReadInstrumentResult : byte
            {
                One = 0x52,

                Two = 0x4E,

                Three = 0x54,

                Four = ASCII_ExchangeToHex.Star,
            }
            /// <summary>
            /// 查询程控交流源预制参数命令
            /// </summary>
            public enum An_QueryInstrumentData : byte
            {
                One = 0x52,

                Two = 0x4E,

                Three = 0x53,

                Four = ASCII_ExchangeToHex.Star,
            }
        }

        public struct An_InstrumentsCommonData
        {
            public decimal voltage;

            public decimal frequency;

            public bool lockstatus;
        }
        #endregion //

        #region -- 公共函数
        /// <summary>
        /// 校验和计算
        /// </summary>
        /// <param name="data">计算数据</param>
        /// <param name="start">开始位置</param>
        /// <param name="len">计算长度</param>
        /// <returns>计算结果</returns>
        private byte AN_CheckSumCal(byte[] data, int start, int len)
        {
            byte result = 0;
            int sum = 0;
            for (int a = start; a < len; a++)
            {
                sum += data[a];  //计算和
            }
            result = (byte)sum;  //转换数据
            return result;
        }

        /// <summary>
        /// 串口接收数据校验
        /// </summary>
        /// <param name="recievedata">接收到的数据</param>
        /// <param name="setlenth">设定接收长度</param>
        /// <param name="err_info">错误信息</param>
        private void ReceiveData_Check(byte[] recievedata, int setlenth, out string err_info)
        {
            if (recievedata.Length != setlenth)
            {
                err_info = "数据接收长度不匹配!";
            }
            else
            {
                if (recievedata[0] == (byte)An_CommunicationProtocol.An_Header && recievedata[setlenth - 1] == (byte)An_CommunicationProtocol.An_Frame)
                {
                    if (recievedata[setlenth - 2] != AN_CheckSumCal(recievedata, 1, setlenth - 3))
                    {
                        err_info = "接收数据校验错误!";
                    }
                    else
                    {
                        err_info = string.Empty;
                    }
                }
                else
                {
                    err_info = "数据接收内容错误!";
                }
            }
        }

        /// <summary>
        /// AN97002程控交流源数据发送
        /// </summary>
        /// <param name="port">串口号</param>
        /// <param name="data">发送数据</param>
        /// <param name="error_inf">错误信息</param>
        private void AN_Send_Data(SerialPort port, byte[] data, out string error_inf)
        {
            error_inf = string.Empty;                       //错误信息，空成功，其他为错误信息
            port.BaudRate = AN97002_BaudRate;               //波特率设置(此处会改变原变量的值)
            try
            {
                if (port.IsOpen == false) port.Open();     //如果串口没有被打开则打开串口
                Thread.Sleep(10);                          //延时10ms，防止连续通讯异常
                port.ReadExisting();                       //发送前先清空缓冲区
                port.Write(data, 0, data.Length);          //发送数据
            }
            catch (Exception ex)
            {
                error_inf = "通讯故障:" + ex.ToString();   //通讯错误，串口故障
            }
        }
        /// <summary>
        /// AN97002程控交流源数据接收
        /// </summary>
        /// <param name="port">串口号</param>
        /// <param name="error_inf">错误信息</param>
        /// <returns>接收数据</returns>
        private byte[] AN_Read_Data(SerialPort port, out string error_inf)
        {
            error_inf = string.Empty;           //错误信息，空成功，其他为错误信息
            byte[] result = new byte[26];       //返回结果，为26个字节byte数组,初始为0
            byte[] receive_data = new byte[0];  //接收数据缓冲区
            int receive_len = 0;                //接收数据字节数量
            int receive_len_last = 0;           //上次接收数据字节数量
            bool dataReceivedCorrectly = false; // 数据接收正确的标志
            port.BaudRate = AN97002_BaudRate;   //波特率设置(此处会改变原变量的值)
            try
            {
                if (port.IsOpen == false) port.Open();                   //如果串口没有被打开则打开串口
                for (int a = 0; a < 50 && !dataReceivedCorrectly; a++)   //最长等待50*10ms
                {
                    receive_len = port.BytesToRead;                         //获取接收字节数量
                    if (receive_len > 0 && receive_len == receive_len_last)  //AN97002数据回复,此仪表回复数据存在间断，故增加数据长度判断
                    {
                        Array.Resize(ref receive_data, receive_len);  //重定义数组长度
                        port.Read(receive_data, 0, receive_len);      //读取数据
                        dataReceivedCorrectly = true;
                    }
                    Thread.Sleep(10);                 //延时10ms
                    receive_len_last = receive_len;   //上次接收数据字节数量赋值
                    if (dataReceivedCorrectly) break;
                }
                if (!dataReceivedCorrectly)
                {
                    error_inf = "通讯错误，回复数据超时";   //通讯错误，回复数据超时
                }
                else
                {
                    result = receive_data;
                }
            }
            catch (Exception e)
            {
                error_inf = "通讯错误，串口故障" + e.ToString();   //IT8512A电子负载，通讯错误，串口故障
            }
            return result;
        }
        /// <summary>
        /// ASCII码转换函数
        /// </summary>
        /// <param name="num">输入字符串数值</param>
        /// <returns>字节数组</returns>
        public static byte[] ASCII_ToHex(string num)
        {
            // 将数字字符串的每个字符转换为其ASCII码的16进制表示
            List<byte> hexBytesList = new List<byte>();
            foreach (char c in num)
            {
                hexBytesList.Add((byte)c);
            }
            return hexBytesList.ToArray();
        }
        #endregion //

        #region --相关数据填充
        /// <summary>
        /// 启动程控交流源数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        private byte[] AnInstrument_StartDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_InstrumentStrat.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_InstrumentStrat.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_InstrumentStrat.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_InstrumentStrat.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }
        /// <summary>
        /// 停止程控交流源数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        private byte[] AnInstrument_StopDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_InstrumentStop.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_InstrumentStop.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_InstrumentStop.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_InstrumentStop.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }
        /// <summary>
        /// 设置程控交流源常规测量参数
        /// </summary>
        /// <param name="address">程控交流源地址</param>
        /// <param name="voltage">电压</param>
        /// <param name="frequency">频率</param>
        /// <param name="upfloat">上浮值</param>
        /// <param name="downfloat">下浮值</param>
        /// <param name="fastlock">快捷组和高档锁定</param>
        /// <returns>数据填充结果</returns>
        private byte[] AnInstrument_SetCommonMeasurementParameters(uint address, string voltage, string frequency, string upfloat, string downfloat, string fastlock)
        {
            byte[] send_cmd = new byte[30];
            byte[] string_voltage = new byte[4];
            byte[] string_frequency = new byte[4];
            byte[] string_upfloat = new byte[2];
            byte[] string_downfloat = new byte[2];
            byte[] string_fastlock = new byte[2];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 27;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Four;
            string_voltage = ASCII_ToHex(voltage);
            Buffer.BlockCopy(string_frequency, 0, send_cmd, 8, 4);
            send_cmd[12] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Five;

            string_frequency = ASCII_ToHex(frequency);
            Buffer.BlockCopy(string_frequency, 0, send_cmd, 13, 4);
            send_cmd[17] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Five;

            string_upfloat = ASCII_ToHex(upfloat);
            Buffer.BlockCopy(string_upfloat, 0, send_cmd, 18, 2);
            send_cmd[20] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Five;

            string_downfloat = ASCII_ToHex(downfloat);
            Buffer.BlockCopy(string_downfloat, 0, send_cmd, 22, 2);
            send_cmd[24] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Five;

            string_fastlock = ASCII_ToHex(fastlock);
            send_cmd[25] = string_fastlock[0];
            send_cmd[26] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Five;
            send_cmd[27] = string_fastlock[1];
            send_cmd[28] = (byte)An_InstrumentSendCmd.An_InstrumentSetData.Six;
            send_cmd[29] = AN_CheckSumCal(send_cmd, 1, 27);
            return send_cmd;
        }
        /// <summary>
        /// 程控交流源读取仪器型号数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        public byte[] AnInstrument_ReadTypeDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_ReadInstrumentType.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_ReadInstrumentType.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_ReadInstrumentType.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_ReadInstrumentType.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }

        /// <summary>
        /// 程控交流源读取仪器版本数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        public byte[] AnInstrument_ReadEdtionDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_ReadInstrumentEdition.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_ReadInstrumentEdition.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_ReadInstrumentEdition.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_ReadInstrumentEdition.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }
        /// <summary>
        /// 程控交流源读取仪器状态数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        public byte[] AnInstrument_ReadStatusDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_ReadInstrumentStatus.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_ReadInstrumentStatus.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_ReadInstrumentStatus.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_ReadInstrumentStatus.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }

        /// <summary>
        /// 程控交流源读取测试结果数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        public byte[] AnInstrument_ReadResultDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_ReadInstrumentResult.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_ReadInstrumentResult.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_ReadInstrumentResult.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_ReadInstrumentResult.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }

        /// <summary>
        /// 程控交流源查询预制参数数据填充
        /// </summary>
        /// <param name="address">交流源地址</param>
        /// <returns>数据填充结果</returns>
        public byte[] AnInstrument_QueryPrepareDataFilling(uint address)
        {
            byte[] send_cmd = new byte[10];
            send_cmd[0] = (byte)An_CommunicationProtocol.An_Header;
            send_cmd[1] = 7;
            send_cmd[2] = (byte)((address >> 16) & 0xFF); // 高位
            send_cmd[3] = (byte)(address & 0xFF);         // 低位（实际上是低16位的低8位）
            send_cmd[4] = (byte)An_InstrumentSendCmd.An_QueryInstrumentData.One;
            send_cmd[5] = (byte)An_InstrumentSendCmd.An_QueryInstrumentData.Two;
            send_cmd[6] = (byte)An_InstrumentSendCmd.An_QueryInstrumentData.Three;
            send_cmd[7] = (byte)An_InstrumentSendCmd.An_QueryInstrumentData.Four;
            send_cmd[8] = AN_CheckSumCal(send_cmd, 1, 7);
            send_cmd[9] = (byte)An_CommunicationProtocol.An_Frame;
            return send_cmd;
        }
        #endregion


        #region -- 功能函数
        /// <summary>
        /// 开启/关闭程控交流源
        /// </summary>
        /// <param name="port">串口号</param>
        /// <param name="address">地址</param>
        /// <param name="status">开关状态</param>
        /// <param name="err_info">错误信息</param>
        /// <returns>返回是否成功</returns>
        public bool Function_SwitchAnInstrument(SerialPort port, uint address, bool status, out string err_info)
        {
            bool openseccuss = false;
            byte[] recievedata = new byte[13];
            err_info = string.Empty;
            int datalenth = 0;
            for (int i = 0; i < 3; i++)
            {
                if (!status) AN_Send_Data(port, AnInstrument_StopDataFilling(address), out err_info);//关闭程控电源
                else AN_Send_Data(port, AnInstrument_StartDataFilling(address), out err_info);//打开程控电源
                if (!string.IsNullOrEmpty(err_info))
                {
                    openseccuss = false;
                    err_info = "发送数据错误,请检查串口!";
                    return false;
                }
                else
                {
                    recievedata = AN_Read_Data(port, out err_info);
                    if (!string.IsNullOrEmpty(err_info))
                    {
                        openseccuss = false;
                        err_info = "接收数据错误,请检查串口!";
                        return false;
                    }
                    else
                    {
                        if (recievedata.Length != 0)
                        {
                            datalenth = recievedata.Length;
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
            if (datalenth == 0)
            {
                openseccuss = false;
                err_info = "数据接收超时!";
            }
            else
            {
                ReceiveData_Check(recievedata, 13, out err_info);
                if (!string.IsNullOrEmpty(err_info))
                {
                    openseccuss = false;//打开失败
                }
                else
                {
                    openseccuss = true;//打开成功
                }
            }
            return openseccuss;
        }

        public void Function_SetAnInstrumentCommonData(SerialPort port,uint address, decimal voltage,decimal frequency,bool lockstutus,out string err_info)
        {
            err_info = string.Empty;
        }

        #endregion//
    }
}
